0 SCREEN1,2,0:COLOR2,1,4:A$="":FORT=1TO5:A$=A$+A$:NEXT:V=14336:Y=96:R=1:B=255

Setting screen mode 1 (text mode with graphic support), 16x16 sprites (0=8x8,1=8x8 magnified,2=16x16,3=16x16magnified),keyclick off(1=keyclick on)
Setting color foreground, background and border. Settings A$ as a 32 chars long. V=sprite shape definition start address. Y=start position
of player ship sprite. R=temp variable used to increment position in a loop in line2. B=horizontal position of enemy ship

1 CLS:P=0:B$="F87F3F1F1F1F3F7C0000E09EFFFEE00000000779FF7F07001FFEFCF8F8F8FC3E"

clear the screen. P=score value. b$ contains sprite definitions data in hexadecimal notation

2 FORK=1TO4:FORT=0TO7:VPOKEV+T,VAL("&h"+MID$(B$,R,2)):R=R+2:NEXT:V=V+16:NEXT:D=0

we have to define 2 16x16 sprites. every sprites consists of 4 squares of 8x8 pixels, in this order:

1 3
2 4

For our pourpose we need only to define square 1 and 3 of sprite 0 (player ship) and 1 and 3 of sprite1 (enemy ship). So we define 4 squares 
(fork=1to4) of 8 valueas each (fort=0to7) in VRAM. so we do 4 times (fork=1to4) VPOKE (poke in VRAM) V (sprite definitions start address) + T 
(increment address 8 times (fort=0to7 starting from 0 to avoid skipping a position), value (VAL) "&H" (hexadecimal msx basic suffix)+ 2 alfanumeric 
chars taken from b$, at R position (MID$(b$,r,2)). R is incremented by 2 in the inner loop, so every time the loop point to next byte of sprite 
definition address R point to next 2chars group inside b$ (hexadecimal are always 2chars long in 0-255 range). At the end of the inner loop (square 
loop) V is incremented by 16 units, so every time a new square loop starts the sprite definition address is 16bytes higher avoiding a square. So at 
the end of the outer loop we have defined squares 1,3 of sprite0 and 1,3 of sprite 1. D is a flag resetted when enemy ship is fired or if it has 
reached the left border of the screen

3 VPOKEV+6,B:FORK=1TO40:J=INT(RND(1)*767):VPOKE6144+J,46:NEXT:G=2:F=1:I=209:W=I

At the end of sprites definition loop V is incremented by 16 the last time too, so point to square 1 of sprite2. We add 6 to reach the seventh
line of the sprite2 first square and vpoke 255 there (so we have a 8 pixel long line, that we use as player bullet). We have used B definition to 
save space. We put 40 stars in the sky: msx screen is 768 chars long (32x24) so we calc a random number from 0 to 767 and add it to screen start 
address (6144) and VPOKE there a dot character (asc 46). Setting G and F variables: we will use them in game loop to change the A$ string position 
on screen, making a scrolling illusion. I=209 starting y address of enemy ship. 209 is out of visible screen (msx screen is 256x192 pixels). 
Setting W equal to I. I will change during the game, W will never change

4 KEYOFF:LOCATE0,0:?"SCORE";P:VPOKE8197,241:IFB<0THENB=255:D=0

Here starts the code that will be executed during the game. Keyoff erase F-keys description from the bottom of the screen. We hadn't enough space 
to do it before so this will be done during each loop in the game. Print from left top position the SCORE writing, score value (P) and set background 
and foreground colors for the group of characters from 48 to 55, where the dot character is located and we used it as star in prec line. We check 
if enemy ship coordinate is less than 0 (the enemy ship reached left border). If so set B to 255 again (rightmost pixel on screen, ready to start 
again) and reset flag D to 0 (enemy is out of screen)

5 J=STICK(0):S=STRIG(0):B=B-16:K=K+16:IFD=0THENC=8*(INT(RND(1)*20)+1):D=1

stick is a function to read joystick or cursor keys values (0 cursors,1 joy in port1, 2 joy in port2). strig read fire buttons (0 spacebar, 1 joy1
fire1, 2 joy2 fire1, 3 joy1 fire2, 4 joy2 fire2). B (enemy ship x coordinate) is decremented by 16, K (we haven't deined before so it is 0, is the 
player bullet x position) is increased by 16 (it will be affect bullet sprite, when on screen). If D=0 we know that the enemy ship has reached the 
left border or it has been fired. In both cases we have to set a new y position for a new enemy ship. This coordinate is the variable C and we set 
it as a random number from 1 to 21: we add 1 at the end to avoid value 0 and set D=1 (enemy on screen flag)

6 Y=Y-8*(J=5ANDY<153)+8*(J=1ANDY>15):PUTSPRITE1,(16,Y),15,0:PUTSPRITE2,(B,C),8,1

Our ship can only move up or down and does it in 8pixels steps. so Y will increase (move down) by 8 if J (stick function)=5 and decrease (move up) 
if j=1. And we have to set movement limits too. To save space we do it by a math formula: we add to y -8 and +8 multiplicated the conditions inside 
brackets. if conditions are true then the multiplication is by -1. If false we multiply by 0. So if the conditions are true multiply -1 by -8 will 
give us a positive value, other side -1 * 8 will give us -8. Sprites 0(player) and 1(enemy) are displayed on screen. putsprite parameters are number 
of display plane (lesser nr has most priority),(x,y),color,sprite nr

7 IFC=YANDB<32THENCLS:VPOKE6912,208:LOCATE7,12:?"FINAL SCORE";P:LOCATE0,0:END

If C(enemy y position) is equal to Y (player y position) and B(enemy x position) is less than 32 then we have a collision for sure, 'cause our ship 
is always at x=16 position (so is displayed from 16 to 32). In that case we clear the screen and write in VRAM the value 208 to the first sprite y 
position address. 208 is a "magic number": if a sprite y is set to 208 that sprites and all the subsequent sprites are removed from screen. So setting 
the first sprite y to 208 removes for sure all sprites from screen. Then we print the score at the center of the screen and set cursor position to the 
left top position before exit (to prevent writings to be cleared, we haven't enough space to clear the keybuffer)

8 LOCATE0,21:?MID$(A$,F,29):SWAPF,G:PUTSPRITE3,(K,I),5,2:IF(S)THENI=Y:K=32

here is the pseudo scrolling: we print the string A$, starting from character in F position at firsth coloumn, 22th row. Then we swap F and G variables
 so every turn F will be 1 or 2 and the string will be displayed offsetted by a char... bullet sprite is displayed on screen at K (x coordinate) and I 
(y coordinate): if spacebar (trigger 0) is pressed then I will assume the same value of Y (player ship y coordinate) and K (bullet x coordinate) will 
be set as 32 (just in front of player ship)

9 IFK>=BANDI=CTHENP=P+10:D=0:B=255:I=W:GOTO4ELSEIFK=240THENI=W:GOTO4ELSE4

If K (bullet x) is equal or biggerthan B (enemy ship x coord) and I (bullet y) is equal to C (enemy ship y) then there is a collision between them. 
The score is incremented by 10, D (enemy on screen flag) is resetted and B is set to 255 (as it started). I (bullet y) is set equal to W (209, to put 
bullet out of screen) saving 2 chars and the game can continue again from line4 else if K (bullet x) is bigger than 240 then it is out of screen and 
I is set to 209 to avoid display it. The game can contniue from line 4 else it has to continue to line 4 (without this last else the game would end 
if a bullet reaches x=240)


Pintus Giuseppe Ettore
thegeps@gmail.com